import asyncio
import math
import random

import pygame

from bullet import Bullet
from plant import Plant
from uiUtil import gameBgImg, drewImg, drawText
from stages import stage1
from zombie import Zombie

bg = pygame.image.load('assets/img/bg.png')
bg0 = pygame.image.load('assets/img/Items/Background/Background_0.jpg')
chooserBg = pygame.image.load('assets/img/Screen/ChooserBackground.png')
img_gameover = pygame.image.load('assets/img/gameover.png')

# 道具卡
img_card_sunflower = pygame.image.load('assets/img/Cards/card_sunflower.png')
img_card_peashooter = pygame.image.load('assets/img/Cards/card_peashooter.png')
img_card_repeaterpea = pygame.image.load('assets/img/Cards/card_repeaterpea.png')
img_card_snowpea = pygame.image.load('assets/img/Cards/card_snowpea.png')
img_card_wallnut = pygame.image.load('assets/img/Cards/card_wallnut.png')
img_card_chomper = pygame.image.load('assets/img/Cards/card_chomper.png')
img_card_cherrybomb = pygame.image.load('assets/img/Cards/card_cherrybomb.png')
img_card_spikeweed = pygame.image.load('assets/img/Cards/card_spikeweed.png')
# 植物
img_car = pygame.image.load('assets/img/car.gif')
imgs_Sun = [pygame.image.load('assets/img/Plants/Sun/Sun_' + str(i) + '.png') for i in range(22)]
imgs_SunFlower = [pygame.image.load('assets/img/Plants/SunFlower/SunFlower_'+str(i)+'.png') for i in range(18)]
# 豌豆
imgs_Peashooter = [pygame.image.load('assets/img/Plants/Peashooter/Peashooter_'+str(i)+'.png') for i in range(13)]
# 牛逼豌豆
imgs_RepeaterPea = [pygame.image.load('assets/img/Plants/RepeaterPea/RepeaterPea_'+str(i)+'.png') for i in range(15)]
# 冰豌豆
imgs_SnowPea = [pygame.image.load('assets/img/Plants/SnowPea/SnowPea_'+str(i)+'.png') for i in range(15)]
# 土豆子
imgs_WallNut = [pygame.image.load('assets/img/Plants/WallNut/WallNut/WallNut_'+str(i)+'.png') for i in range(16)]
# 大嘴花
imgs_Chomper = [pygame.image.load('assets/img/Plants/Chomper/Chomper/Chomper_'+str(i)+'.png') for i in range(13)]
# 樱桃
imgs_CherryBomb = [pygame.image.load('assets/img/Plants/CherryBomb/CherryBomb_'+str(i)+'.png') for i in range(7)]
#南瓜
imgs_Spikeweed = [pygame.image.load('assets/img/Plants/Spikeweed/Spikeweed/Spikeweed_'+str(i)+'.png') for i in range(19)]

# 加载僵尸
imgs_BucketheadZombie = [pygame.image.load('assets/img/Zombies/BucketheadZombie/BucketheadZombie/BucketheadZombie_'+str(i)+'.png') for i in range(15)]
imgs_ConeheadZombie = [pygame.image.load('assets/img/Zombies/ConeheadZombie/ConeheadZombie/ConeheadZombie_'+str(i)+'.png') for i in range(21)]
imgs_FlagZombie = [pygame.image.load('assets/img/Zombies/FlagZombie/FlagZombie/FlagZombie_'+str(i)+'.png') for i in range(12)]
imgs_NewspaperZombie = [pygame.image.load('assets/img/Zombies/NewspaperZombie/NewspaperZombie/NewspaperZombie_'+str(i)+'.png') for i in range(19)]
imgs_NormalZombie = [pygame.image.load('assets/img/Zombies/NormalZombie/Zombie/Zombie_'+str(i)+'.png') for i in range(22)]

# 加载子弹
img_bullet = pygame.image.load('assets/img/Bullets/PeaNormal/PeaNormal_0.png')

cards = [{"card": img_card_sunflower, "sun": 50},
         {"card": img_card_peashooter, "sun": 50},
         {"card": img_card_repeaterpea, "sun": 50},
         {"card": img_card_snowpea, "sun": 50},
         {"card": img_card_wallnut, "sun": 50},
         {"card": img_card_chomper, "sun": 50},
         {"card": img_card_cherrybomb, "sun": 50},
         {"card": img_card_spikeweed, "sun": 50}]

plants = [
    {"name":"sunflower", "img":imgs_SunFlower, "hp": 100},
    {"name":"peashooter", "img":imgs_Peashooter, "hp": 100},
    {"name":"repeaterpea", "img":imgs_RepeaterPea, "hp": 100},
    {"name":"snowpea", "img":imgs_SnowPea, "hp": 100},
    {"name":"wallnut", "img":imgs_WallNut, "hp": 100},
    {"name":"chomper", "img":imgs_Chomper, "hp": 100},
    {"name":"cherrybomb", "img":imgs_CherryBomb, "hp": 100},
    {"name":"squash", "img":imgs_Spikeweed, "hp": 100},
    {"name":"car", "img":img_car, "hp": 999}
]

zombieList = [
    {"name":"BucketheadZombie", "img":imgs_BucketheadZombie, "hp": 100, "harm": 10},
    {"name":"ConeheadZombie", "img":imgs_ConeheadZombie, "hp": 100, "harm": 10},
    {"name":"FlagZombie", "img":imgs_FlagZombie, "hp": 100, "harm": 10},
    {"name":"NewspaperZombie", "img":imgs_NewspaperZombie, "hp": 100, "harm": 10},
    {"name":"NormalZombie", "img":imgs_NormalZombie, "hp": 100, "harm": 10}
]
# 生成一个5*10的数组，用于放植物
grids = [["." for _ in range(10)] for _ in range(5)]

plantGroup = pygame.sprite.Group()
sunGroup = pygame.sprite.Group()
zombieGroup = pygame.sprite.Group()
bulletGroup = pygame.sprite.Group()

class MainPlantsAndZombies:

    def __init__(self, dims, FPS=60):
        self.dims = dims
        self.FPS = FPS
        # 游戏运行控制变量（gamen_running）
        self.game_running = True
        # 选中的道具卡
        self.selectedCard = None
        self.selectedCardPos = None
        # 第一关
        self.stage = 1
        # 僵尸计数
        self.zombieFrequency = 50
        self.zombioBatch = 0
        self.score = 50

    # 1:小车
    def initGrids(self):
        for row in range(5):
            grids[row][0] = 9
            plantGroup.add(Plant([img_car], (80, 80), (180, 180 + 100 * row), "car"))

    def drawGrid(self, screen):
        for plant in plantGroup:
            plant.draw(screen)
            plant.update()
            # 晃完一圈产生一个太阳
            if plant.plantName == "sunflower" and plant.currentImgIndex == 0:
                if plant.count > 4:
                    sunGroup.add(Plant(imgs_Sun, (80, 80), plant.position, "Sun"))
                    plant.count = 0
            # 晃一圈产生一个子弹
            if plant.plantName == "peashooter" and plant.currentImgIndex == 0:
                if plant.count > 2:
                    bulletGroup.add(Bullet(img_bullet, (plant.position[0]+40,plant.position[1]+20)))
                    plant.count = 0

    async def start(self):
        # 初始化pygame，预定义各种常量
        pygame.init()
        # 初始化游戏界面（screen）：尺寸、背景色等
        screen = pygame.display.set_mode(self.dims)
        # 显示游戏名称
        pygame.display.set_caption("植物大战僵尸")
        # 初始化游戏时钟（clock），由于控制游戏帧率
        clock = pygame.time.Clock()
        # 播放背景音乐
        # playMyBgMusic('')

        self.initGrids()
        # 游戏主循环
        while True:
            # 按照给定的 FPS 刷新游戏
            # clock.tick() 函数返回上一次调用该函数后经历的时间，单位为毫秒 ms
            # dt 记录上一帧接受之后经历的时间，单位为秒 m
            # 使用 dt 控制物体运动可以使游戏物理过程与帧率无关
            dt = clock.tick(self.FPS) / 1000.0
            # 使用 asyncio 同步
            # 此外游戏主体代码中不需要再考虑 asyncio
            await asyncio.sleep(0)

            # 游戏事件处理
            # 包括键盘、鼠标输入等
            for event in pygame.event.get():
                # 点击关闭窗口按钮或关闭网页
                if event.type == pygame.QUIT:
                    pygame.quit()
                if event.type == pygame.MOUSEMOTION:
                    # 画一个选中的图，跟随鼠标走
                    pos = event.pos
                    if self.selectedCard is not None:
                        self.selectedCardPos = pos
                if event.type == pygame.MOUSEBUTTONDOWN:
                    mouse_presses = pygame.mouse.get_pressed()
                    if mouse_presses[0]:    # 左键
                        pos = event.pos
                        if pos[0] > 64 and pos[0] < 64 + 64 * 8 and pos[1] > 0 and pos[1] < 90:
                            cardIndex = math.floor((pos[0] -64)/64)
                            # 判断点击到哪个卡片
                            self.selectedCard = cardIndex
                            self.selectedCardPos = pos
                        else:
                            # 把植物种到地里
                            # 计算鼠标位置
                            if pos[0]>250 and pos[0]<990 and pos[1]>170 and pos[1]<670:
                                if self.selectedCard is not None:
                                    row_index = math.floor((pos[1] - 170) / 100)
                                    col_index = math.floor((pos[0]-250)/80)
                                    # print(f"row_index:{row_index}, col_index:{col_index + 1}")
                                    # print(grids)
                                    if grids[row_index][col_index + 1] == ".":
                                        x = 250+col_index*80
                                        y = 170+row_index*100
                                        plantGroup.add(Plant(plants[cardIndex]["img"], (80, 80), (x, y), plants[cardIndex]["name"]))
                                        self.selectedCard = None
                                        # 给这个网格设置值
                                        grids[row_index][col_index + 1] = cardIndex
                                    else:
                                        self.selectedCard = None
                                else:
                                    # 检测精灵是否被点击
                                    for sun in sunGroup:
                                        if sun.collidePoint(pos):
                                            self.score += 50
                                            sunGroup.remove(sun)
                                            # print("精灵被点击！")
                                    # sunGroup.

                            # screen.blit(cards[self.selectedCard],pos)
                    if mouse_presses[2]:    # 右键
                        self.selectedCard = None

            # 碰撞检测，子弹碰到僵尸
            self.CollisionBulletAndZombie(bulletGroup, zombieGroup)
            # 碰撞检测，僵尸碰到植物
            self.CollisionZombieAndPlant(zombieGroup, plantGroup)
            # 以背景色覆盖刷新游戏界面
            self.drawBackground(screen)
            # 画分数
            pygame.draw.rect(screen, [255,255,0],[10,65,55,20],0)
            screen.blit(pygame.font.SysFont("SimHei", 16, True).render(str(self.score), True, "black"), (15,66))

            # 画卡片
            for index, card in enumerate(cards):
                drewImg(screen, card["card"], 0, (64,90), (64 + 64*index, 0))

            # 画植物
            self.drawGrid(screen)
            # 画太阳
            for sun in sunGroup:
                sun.draw(screen)
                sun.update()
                if sun.count > 2:
                    sunGroup.remove(sun)
            # 画子弹
            bulletGroup.update()
            bulletGroup.draw(screen)

            # 创建一批僵尸
            if self.zombioBatch < len(stage1):
                if self.zombieFrequency>100:
                    zombies = stage1[self.zombioBatch]
                    self.zombioBatch += 1

                    self.zombieFrequency = 0
                    for zombie in zombies:
                        zombieInfo = zombieList[zombie]
                        zombieGroup.add(Zombie(zombieInfo["img"],(1000 + random.randint(100,300), 130 + 100 * random.randint(0,4)), zombieInfo["name"]))
            self.zombieFrequency += 1
            # 画僵尸
            for zombie in zombieGroup:
                if zombie.update():
                    zombie.draw(screen)
                else:
                    # 画僵尸吃掉你的脑子
                    screen.blit(img_gameover,(500,200))

            # 画选中的卡片
            if self.selectedCard is not None and self.selectedCardPos is not None:
                screen.blit(cards[self.selectedCard]["card"], self.selectedCardPos)


            # drawText(f"x:{self.selectedCardPos[0]};y:{self.selectedCardPos[1]}", "black", (10, 10), screen)
            # 将游戏界面内容输出至屏幕
            pygame.display.update()

            # 跳出游戏主循环，退出游戏
        cfg.inGame = False

    def drawBackground(self, screen):
        gameBgImg(screen, bg, 270, self.dims)
        drewImg(screen, chooserBg, 0, (522, 90), (0, 0))
        drewImg(screen, bg0, 0, (self.dims[0], self.dims[1] - 90), (0, 90))

    def CollisionBulletAndZombie(self, bulletGroup, zombieGroup):
        collisions =  pygame.sprite.groupcollide(bulletGroup, zombieGroup, True, False)
        if collisions:
            for zombies in collisions.values():
                for zombie in zombies:
                    zombie.hp -=1
                    if zombie.hp <=0:
                        zombieGroup.remove(zombie)

    def CollisionZombieAndPlant(self, zombieGroup, plantGroup):
        pass


if __name__ == '__main__':
    asyncio.run(MainPlantsAndZombies((1400, 690), FPS=30).start())